package cn.com.open.itembank.logic.importfilereader;
import cn.com.open.itembank.common.CommonFunction;
import cn.com.open.itembank.common.NpoiHelper;
import cn.com.open.itembank.common.enums.ImportType;
import cn.com.open.itembank.dto.QuestionImportModel;
import cn.com.open.itembank.utils.StringUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Created by lucky on 2017/12/15.
 */
public class ExcelFileReader implements FileReader {

    private static org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(ExcelFileReader.class);

    /**
     * 得到文件类型.
     *
     * @return the import type
     */
    @Override
    public ImportType getImportType() {
        return ImportType.EXCEL;
    }

    /**
     * 得到数据模型.
     *
     * @param filePath the file path
     */
    @Override
    public List<QuestionImportModel> getDataList(String filePath,String extendName) {
        Map<Integer, Map<Integer, Object>> content = getExcelList(filePath);

        return fillData(content);
    }

    //region 读取excel数据

    /**
     * 读取excel数据.
     *
     * @param filePath the file path
     * @return the excel list
     */
    private Map<Integer, Map<Integer, Object>> getExcelList(String filePath) {
        // 转换为excel通用泛型
        NpoiHelper excelReader = new NpoiHelper(filePath);
        Map<Integer, Map<Integer, Object>> content = null;

        try {
            content = excelReader.readExcelContent();
        } catch (Exception e) {
            logger.error(e.getMessage());
        }

        return content;
    }
    //endregion

    //region 补齐子试题节点

    /**
     * 补齐子试题节点.
     *
     * @param subItemModelList the sub item model list
     * @param count            the count
     */
    private void fillSubItemModelList(List<QuestionImportModel> subItemModelList, int count) {
        for (int i = 0; i < count; i++) {
            QuestionImportModel subItemModel = new QuestionImportModel();
            subItemModelList.add(subItemModel);
        }
    }
    //endregion

    //region 填写子试题题干

    /**
     * 填写子试题题干.
     *
     * @param subItemModelList the sub item model list
     * @param subContentList   the sub content list
     */
    private void setSubPrompt(List<QuestionImportModel> subItemModelList, List<String> subContentList) {
        for (int j = 0; j < subItemModelList.size(); j++) {
            subItemModelList.get(j).setPrompt(subContentList.get(j));
        }
    }
    //endregion

    //region 填写子试题答案

    /**
     * 填写子试题答案.
     *
     * @param subItemModelList the sub item model list
     * @param answersList      the answers str list
     */
    private void setSubAnswer(List<QuestionImportModel> subItemModelList, List<String> answersList) {
        for (int j = 0; j < answersList.size(); j++) {
            subItemModelList.get(j).getAnswer().addAll(CommonFunction.getListRemoveEmptyEntities(answersList.get(j), CommonFunction.SEPARATOR));
        }
    }
    //endregion

    //region 填写子试题分数

    /**
     * 填写子试题分数.
     *
     * @param subItemModelList the sub item model list
     * @param subScoreList     the sub score list
     */
    private void setScore(List<QuestionImportModel> subItemModelList, List<String> subScoreList) {
        for (int j = 0; j < subItemModelList.size(); j++) {
            subItemModelList.get(j).setScore(subScoreList.size() < j ? subScoreList.get(j) : "0");
        }
    }
    //endregion

    //region 填写子试题解析

    /**
     * 填写子试题解析.
     *
     * @param subItemModelList    the sub item model list
     * @param subQuestionTypeList the sub question type list
     */
    private void setSubQuestionType(List<QuestionImportModel> subItemModelList, List<String> subQuestionTypeList) {
        for (int j = 0; j < subQuestionTypeList.size(); j++) {
            subItemModelList.get(j).setQuestionType(subQuestionTypeList.get(j));
        }
    }
    //endregion

    //region 计算试题分数

    /**
     * 计算试题分数.
     *
     * @param subItemModelList the sub item model list
     * @return the item score
     */
    private String getItemScore(List<QuestionImportModel> subItemModelList) {
        double sumScore = 0;
        for (QuestionImportModel subItem : subItemModelList) {
            sumScore += Double.valueOf(subItem.getScore());
        }

        return String.valueOf(sumScore);
    }
    //endregion

    //region 创建子试题模型

    /**
     * 创建子试题模型.
     *
     * @param parentItem 父试题
     * @param subChoices 子试题选项串
     * @return the question import model
     */
    private QuestionImportModel makeSubItem(QuestionImportModel parentItem, String subChoices) {
        QuestionImportModel subItemModel = new QuestionImportModel();

        subItemModel.setQuestionCategoryName(parentItem.getQuestionCategory());
        subItemModel.setChoices(CommonFunction.getList(subChoices, CommonFunction.SEPARATOR));
        subItemModel.setChapter(parentItem.getChapter());

        return subItemModel;
    }
    //endregion

    //region 创建试题模型

    /**
     * 创建试题模型.
     *
     * @param content     试题内容原始串
     * @param isObjective 是否是主观题
     * @return the question import model
     */
    private QuestionImportModel makeItem(Map<Integer, Object> content, String isObjective) {
        QuestionImportModel itemModel = new QuestionImportModel();

        itemModel.setQuestionTypeName(content.get(0).toString());
        itemModel.setQuestionCategoryName(content.get(1).toString());
        itemModel.setSaveDiffWord(content.get(2).toString());
        itemModel.setPrompt(content.get(3).toString());
        itemModel.setScore(content.get(7).toString());
        itemModel.setQuestionAnalysis(content.get(8).toString());
        itemModel.setIsObjective(isObjective);

        if (StringUtil.isEmpty(content.get(9).toString())) {
            itemModel.setChapter(content.get(9).toString());
        }

        return itemModel;
    }
    //endregion

    //region 根据选项创建子试题集合

    /**
     * 根据创建子试题集合.
     *
     * @param choicesList the choices list
     * @param itemModel   the item model
     * @return the list
     */
    private List<QuestionImportModel> makeSubItemList(List<String> choicesList, QuestionImportModel itemModel) {
        List<QuestionImportModel> subItemModelList = new ArrayList<>();

        for (String str : choicesList) {
            QuestionImportModel subItemModel = makeSubItem(itemModel, str);

            subItemModelList.add(subItemModel);
        }

        return subItemModelList;
    }
    //endregion

    //region 填充子试题题干

    /**
     * 填充子试题题干.
     *
     * @param choicesList      the choices list
     * @param subContentList   the sub content list
     * @param subItemModelList the sub item model list
     */
    private void getSubContent(List<String> choicesList, List<String> subContentList, List<QuestionImportModel> subItemModelList) {
        if (choicesList.size() >= subContentList.size()) {
            //题干截取的子题数小于等于选项截取的子题数
            setSubPrompt(subItemModelList, subContentList);
        } else {
            //题干截取的子题数大于选项截取的子题数
            fillSubItemModelList(subItemModelList, subContentList.size() - subItemModelList.size());

            setSubPrompt(subItemModelList, subContentList);
        }
    }
    //endregion

    //region 填充子试题答案

    /**
     * 填充子试题答案.
     *
     * @param choicesList      the choices list
     * @param answersList      the answers list
     * @param subItemModelList the sub item model list
     */
    private void getSubAnswer(List<String> choicesList, List<String> answersList, List<QuestionImportModel> subItemModelList) {
        if (choicesList.size() >= answersList.size()) {
            //按选项截取的子题数大于等于按答案截取的子题数
            setSubAnswer(subItemModelList, answersList);
        } else {
            //按选项截取的子题数小于按答案截取的子题数
            fillSubItemModelList(subItemModelList, answersList.size() - subItemModelList.size());

            setSubAnswer(subItemModelList, answersList);
        }
    }
    //endregion

    //region 填充数据

    /**
     * 填充数据.
     *
     * @param content the content
     * @return the list
     */
    private List<QuestionImportModel> fillData(Map<Integer, Map<Integer, Object>> content) {
        List<QuestionImportModel> list = new ArrayList<>();
        QuestionImportModel itemModel;

        if (content.size() < 0) {
            return list;
        }

        for (Map.Entry<Integer, Map<Integer, Object>> map : content.entrySet()) {
            // 如果读到的列数小于10列，证明数据格式不正确
            if (map.getValue().size() < 10) {
                continue;
            }

            // 子题题干内容（如果包含子题，则为多项；如果不含子题，则为一项）
            List<String> subContentList = CommonFunction.getListRemoveEmptyEntities(map.getValue().get(4).toString(), CommonFunction.SUB_ITEM_SEPARATOR);
            // 选项列表（如果包含子题，则为多项；如果不含子题，则为一项）
            List<String> choicesList = CommonFunction.getListRemoveEmptyEntities(map.getValue().get(5).toString(), CommonFunction.SUB_ITEM_SEPARATOR);
            // 答案（如果包含子题，则为多项；如果不含子题，则为一项）
            List<String> answersList = CommonFunction.getListRemoveEmptyEntities(map.getValue().get(6).toString(), CommonFunction.SUB_ITEM_SEPARATOR);
            // 是否客观
            String isObjective = map.getValue().size() > 11 ? map.getValue().get(10).toString() : "是";

            // 实例化一个试题传输模型（不含选项、答案、子题）
            itemModel = makeItem(map.getValue(), isObjective);

            if (choicesList.size() > 1) {
                // 有子题
                List<QuestionImportModel> subItemModelList = makeSubItemList(choicesList, itemModel);

                // 处理子题题干
                if (subContentList.size() > 1) {
                    getSubContent(choicesList, subContentList, subItemModelList);
                } else if (subContentList.size() == 1) {
                    List<String> subPromptList = CommonFunction.getListRemoveEmptyEntities(subContentList.get(0), CommonFunction.SEPARATOR);
                    getSubContent(choicesList, subPromptList, subItemModelList);
                }

                // 处理子题答案
                if (answersList.size() > 1) {
                    getSubAnswer(choicesList, answersList, subItemModelList);
                } else if (answersList.size() == 1) {
                    List<String> subAnswerList = CommonFunction.getListRemoveEmptyEntities(answersList.get(0), CommonFunction.SEPARATOR);
                    getSubAnswer(choicesList, subAnswerList, subItemModelList);
                }

                //处理分数
                checkedItemModel(itemModel,subItemModelList,map.getValue().get(9),choicesList);

            }
            // 处理匹配题
            else if (subContentList.size() > 1) {
                //处理选项
                if (choicesList.size() == 1) {
                    itemModel.getChoices().addAll(CommonFunction.getListRemoveEmptyEntities(choicesList.get(0), CommonFunction.SEPARATOR));
                }

                List<QuestionImportModel> subItemModelList = new ArrayList<>();

                for (int i = 0; i < subContentList.size(); i++) {
                    QuestionImportModel questionImportModel = new QuestionImportModel();
                    // 增加子题题干
                    questionImportModel.setPrompt(subContentList.get(i));
                    // 增加子题答案
                    List<String> answers = CommonFunction.getListRemoveEmptyEntities(answersList.get(i), CommonFunction.SEPARATOR);
                    for (String answer : answers) {
                        questionImportModel.getAnswer().add(answer);
                    }
                    subItemModelList.add(questionImportModel);
                }

                //处理分数
                checkedItemModel(itemModel,subItemModelList,map.getValue().get(9),choicesList);

            } else {
                //处理选项
                if (choicesList.size() == 1) {
                    itemModel.getChoices().addAll(CommonFunction.getListRemoveEmptyEntities(choicesList.get(0), CommonFunction.SEPARATOR));
                }

                //处理答案
                if (answersList.size() == 1) {
                    itemModel.getAnswer().addAll(CommonFunction.getListRemoveEmptyEntities(answersList.get(0), CommonFunction.SEPARATOR));
                }
            }

            itemModel.check();
            list.add(itemModel);
        }
        return list;
    }

    /**
     *
     * @param itemModel
     * @param subItemModelList
     * @param map
     * @return
     */
    private void checkedItemModel(QuestionImportModel itemModel,List<QuestionImportModel> subItemModelList,Object map,List<String> choicesList) {

        List<String> subScoreList = CommonFunction.getListRemoveEmptyEntities(itemModel.getScore(), CommonFunction.SEPARATOR);
        if (subScoreList.size() > 1) {
            setScore(subItemModelList, subScoreList);
            itemModel.setScore(getItemScore(subItemModelList));
        }

        // 处理子题解析
        // 以#&#分隔获取主题解析和子题解析
        List<String> analysisList = CommonFunction.getListRemoveEmptyEntities(itemModel.getQuestionAnalysis(), CommonFunction.SEPARATOR);
        if (analysisList.size() == 1) {
            analysisList.add("");
        }
        itemModel.setQuestionAnalysis(analysisList.get(0));
        List<String> subAnalysisList = CommonFunction.getListRemoveEmptyEntities(analysisList.get(1), CommonFunction.SEPARATOR);
        if (subAnalysisList.size() > 1) {
            for (int j = 0; j < subAnalysisList.size(); j++) {
                subItemModelList.get(j).setQuestionAnalysis(subAnalysisList.get(j));
            }
        }

        // 处理子题题型
        if (!StringUtil.isEmpty(map.toString())) {
            List<String> subQuestionTypeList = CommonFunction.getListRemoveEmptyEntities(map.toString(), CommonFunction.SEPARATOR);

            if (subQuestionTypeList.size() > 1) {
                if (choicesList.size() >= subQuestionTypeList.size()) {
                    //按选项截取的子题数大于等于按子题题型截取的子题数
                    setSubQuestionType(subItemModelList, subQuestionTypeList);
                } else {
                    //按选项截取的子题数小于按子题题型截取的子题数
                    fillSubItemModelList(subItemModelList, subQuestionTypeList.size() - subItemModelList.size());
                    setSubQuestionType(subItemModelList, subQuestionTypeList);
                }
            }
        }

        itemModel.getSubItems().addAll(subItemModelList);
    }
    //endregion
}
